#ifndef IINSTANCE_H_INCLUDED
#define IINSTANCE_H_INCLUDED

#include "Transformation.h"
#include "sDataHandle.h"

/// Information
class IInstance {
protected:
	uint 	m_uiID; 						///< Instance ID
	DATAH	m_InstancedData;			///< The data that is instanced

	list<uint>		m_listChildren;///< The children of this istance
	uint				m_uiParent;		///< The parent

	bool	m_bSolid;					///< Is the object collideable?
	bool	m_bVisible;					///< Is the object visible?
	bool	m_bEnabled;					///< Is the object enabled?

private:

public:
	/// Get instance identification
	uint 		GetID		( ) const { return m_uiID; }
	DATAH		GetData	( ) const { return m_InstancedData; }

	/// Get transformational parameters
	virtual vec3r GetViewVector	( ePIE_PARAMSTATE state = NOW ) const = 0; //{ return FORWARD; }
	virtual vec3r GetUpVector		( ePIE_PARAMSTATE state = NOW ) const = 0; // { return UP; }
	virtual vec3r GetRightVector	( ePIE_PARAMSTATE state = NOW ) const = 0; // { return RIGHT; }
	virtual vec3r GetScale			( ePIE_PARAMSTATE state = NOW ) const = 0; // { return ONEVEC; }
	virtual vec3r GetShear			( ePIE_PARAMSTATE state = NOW ) const = 0; // { return ORIGIN; }
	virtual quatr GetOrientation	( ePIE_PARAMSTATE state = NOW ) const = 0; // { return DEFAULT_ORIENTATION; }
	virtual vec3r GetPosition		( ePIE_PARAMSTATE state = NOW ) const = 0; // { return ORIGIN; }
	virtual vec3r GetVelocity		( ePIE_PARAMSTATE state = NOW ) const = 0; // { return ORIGIN; }
	virtual quatr GetSpinVelocity	( ePIE_PARAMSTATE state = NOW ) const = 0; // { return DEFAULT_ORIENTATION; }
	virtual real  GetAccel			( ePIE_PARAMSTATE state = NOW ) const = 0; // { return 0; }
	virtual real  GetSpinAccel		( ePIE_PARAMSTATE state = NOW ) const = 0; // { return 0; }
	virtual mat4r GetTransform		( ePIE_PARAMSTATE state = NOW ) const = 0; // { return IDENTITY_MATRIX; }
	virtual real  GetClock			( ePIE_PARAMSTATE state = NOW ) const = 0; // { return 0; }
	virtual void  GetTransformData( sTransformationData3D **data )  const = 0; // { if(data) *data = NULL; }
	virtual void  GetTransformData( sTransformationData2D **data )  const = 0; // { if(data) *data = NULL; }

	/// Get instance data
	virtual uint			GetParent	( ) const { return m_uiParent;		}
	virtual list<uint>*	GetChildren	( )		 { return &m_listChildren; }

	/// Get flags
	virtual bool IsSolid		( )  const { return m_bSolid;		}
	virtual bool IsVisible	( )  const { return m_bVisible;	}
	virtual bool IsEnabled	( )  const { return m_bEnabled;	}
	virtual bool HasChildren( )  const { return !m_listChildren.empty(); }

	/// Set transformational parameters
	virtual void SetTransformData ( const sTransformationData2D &data, int i = -1 ) { }
	virtual void SetTransformData ( const sTransformationData3D &data, int i = -1 ) { }
	virtual void SetViewVector		( cvec3r &view,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetUpVector		( cvec3r &up,		ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetRightVector	( cvec3r &right,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetScale			( cvec3r &scale,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetShear			( cvec3r &shear,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetOrientation	( cquatr &orient,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetPosition		( cvec3r &pos,		ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetVelocity		( cvec4r &vel,		ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetSpinVelocity	( cquatr &svel,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetAccel			( creal  &accel,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetSpinAccel		( creal  &saccel,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetTransform		( cmat4r &trans,	ePIE_PARAMSTATE state = NOW ) { }
	virtual void SetClock			( creal  &clock,	ePIE_PARAMSTATE state = NOW ) { }

	/// Set instance data
	virtual void SetParent			( uint parent_id ) 	{ }
	virtual void AddChild			( uint child_id ) 	{ }
	virtual void RemoveChild		( uint child_id ) 	{ }

	/// Set flags
	virtual void SetSolid			( bool f = true ) { m_bSolid		=  f;	}
	virtual void Show					( bool f = true ) { m_bVisible	=  f;	}
	virtual void Hide					( bool f = true ) { m_bVisible	= !f;	}
	virtual void Enable				( bool f = true ) { m_bEnabled	=  f;	}
	virtual void Disable				( bool f = true ) { m_bEnabled	= !f;	}

	/// Movement planning
	virtual void MoveToward			( uint obj, creal &spd, bool automatic = false ) { }
	virtual void MoveTo				( cvec3r &pos, creal &spd ) { }
	virtual void MoveToward			( cvec3r &dir, creal &spd ) { }
	virtual void Move					( ) { }

	/// Movement immediate
	virtual void StepToward			( uint obj, creal &spd, creal &dtime ) { }
	virtual void StepTo				( cvec3r &pos, creal &spd, creal &dtime ) { }
	virtual void StepToward			( cvec3r &dir, creal &spd, creal &dtime ) { }
	virtual void StepForward		( creal &spd, creal &dtime ) { }
	virtual void StepRight			( creal &spd, creal &dtime ) { }
	virtual void StepUp				( creal &spd, creal &dtime ) { }

	/// Orientation
	virtual void YawPitchRoll		( creal &yaw, creal &pitch, creal &roll ) { }
	virtual void YawPitch			( creal &yaw, creal &pitch ) { }
	virtual void LookAt				( uint obj, bool automatic = false ) { }
	virtual void LookAt				( cvec3r &pos ) { }
	virtual void Yaw					( creal &deg ) { }
	virtual void Pitch				( creal &deg ) { }
	virtual void Roll					( creal &deg ) { }
	virtual void Look					( ) = 0;

			   // Constructor & Destructor
			   IInstance( ) :
					m_uiID(0),
					m_InstancedData( ),
					m_uiParent(0),
					m_bSolid(false),
					m_bVisible(true),
					m_bEnabled(true) { }
	virtual ~IInstance( ) { }
};




#endif // IINSTANCE_H_INCLUDED
